package processScheduling;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;

public class ProcessScheduling {
    public static  void main(String[] args) {
        new UserInteraction();
    }
}

class ProcessHandle{
    LinkedList<ProcessModel> processQueue=new LinkedList<ProcessModel>();
    ProcessModel highPriProcess;

    public void handleProcess(ProcessModel t){
        processQueue.addLast(t);
        if(processQueue.size()==1){
            processQueue.get(0).start();
        }
    }

    public void runHighPriPro()  {
        if(processQueue.size()>=1){
            try {
                highPriProcess=findHighPriProcess(processQueue);
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }

            if(highPriProcess.equals(Thread.currentThread())==false){
                if(highPriProcess.getState()==Thread.State.NEW){
                    highPriProcess.start();
                }
                else if(highPriProcess.getState()==Thread.State.TIMED_WAITING){
                    highPriProcess.interrupt();
                }

                try {
                    Thread.currentThread().sleep(60*60*1000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                }

            }

        }else{
            UserInteraction.showProRunInfoArea.append("\n所有进程运行完成,请新建进程!\n");
        }
    }


    public ProcessModel findHighPriProcess(LinkedList<ProcessModel> pQueue) throws InterruptedException {
        int p=0;
        int index=-1;
        for(int i=0;i<pQueue.size();i++){
            if(pQueue.get(i).getEPriority()>p){
                p=pQueue.get(i).getEPriority();
                index=i;
            }
        }
        return pQueue.get(index);
    }
}

class ProcessModel extends Thread{
    private int epriority;
    private double eruntime;

    public ProcessModel(String name){
        this.setName(name);
    }

    public int getEPriority() {
        return epriority;
    }

    public void setEPriority(int priority) {
        this.epriority = priority;
    }

    public double getERuntime() {
        return eruntime;
    }

    public void setERuntime(double runtime) {
        this.eruntime = runtime;
    }

    @Override
    public void run() {
        while (this.getERuntime()>0){
            UserInteraction.showProRunInfoArea.append("进程"+Thread.currentThread().getName()+"正在运行,优先级:"+this.epriority+",剩余运行时间:"+this.eruntime+"\n");
            this.eruntime-=3;
            try {
                Thread.currentThread().sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            UserInteraction.processHandle.runHighPriPro();
            }
        UserInteraction.processHandle.processQueue.remove(this);
        UserInteraction.processHandle.runHighPriPro();
    }
}

class UserInteraction extends JFrame implements ActionListener {
    static ProcessHandle processHandle = new ProcessHandle();
    ProcessModel processModel;//模型
    JPanel showProInfoPanel;//视图
    static JTextArea showProRunInfoArea;//视图
    JButton newProButton;//控制器
    JTextField setNameText,setRuntimeText,setPriorityText;
    public UserInteraction(){
        setNameText=new JTextField(5);
        setPriorityText=new JTextField(5);
        setRuntimeText=new JTextField(5);
        newProButton=new JButton("新建进程");
        showProRunInfoArea=new JTextArea();
        showProInfoPanel=new JPanel();
        showProInfoPanel.add(new JLabel("进程名:"));
        showProInfoPanel.add(setNameText);
        showProInfoPanel.add(new JLabel("进程优先级:"));
        showProInfoPanel.add(setPriorityText);
        showProInfoPanel.add(new JLabel("进程所需运行时间(s):"));
        showProInfoPanel.add(setRuntimeText);
        showProInfoPanel.add(newProButton);
        newProButton.addActionListener(this);
        add(showProInfoPanel, BorderLayout.NORTH);
        add(new JScrollPane(showProRunInfoArea),BorderLayout.CENTER);
        showProRunInfoArea.append("采用先来先服务，非抢占式，高优先级，按时间片轮转调度算法，假设CPU时间片为3s;\n");
        setVisible(true);
        setBounds(0,0,600,400);
        setTitle("进程运行信息");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            String name = setNameText.getText().trim();
            int priority = Integer.parseInt(setPriorityText.getText().trim());
            double runtime = Double.parseDouble(setRuntimeText.getText().trim());
            processModel = new ProcessModel(name);
            //processModel.setEName(name);
            processModel.setEPriority(priority);
            processModel.setERuntime(runtime);
            showProRunInfoArea.append("\n新建进程成功，进程名:" + name + " 优先级:" + priority + " 运行时间:" + runtime + "s\n\n");
            processHandle.handleProcess(processModel);

        }catch (Exception ex){
            System.out.println(ex+"\n");
        }

    }
}
